const CLASS_ID = Components.ID("22e580e0-fda9-11de-8a39-0800200c9a66");
const CLASS_NAME = "Convert a forum/blog-like information resource for onthewave postList display";
const POSTLIST_CONTENT_TYPE = 'application/onthewave.postlist';
const POSTLIST_URI = "chrome://on-the-wave/content/post_list.xhtml";
const POST_URI = "chrome://on-the-wave/content/post.xhtml";
const CONTRACT_ID = "@mozilla.org/streamconv;1?from=" + 
                    POSTLIST_CONTENT_TYPE + "&to=*/*"; 
//only convert to text/html but */* is magic see Also <https://developer.mozilla.org/en/Document_Loading_-_From_Load_Start_to_Finding_a_Handler>

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

var gIOService = Cc["@mozilla.org/network/io-service;1"].
                 getService(Ci.nsIIOService);
var Stream = Components.Constructor("@mozilla.org/scriptableinputstream;1",
                                    "nsIScriptableInputStream");
var SIS = Components.Constructor("@mozilla.org/io/string-input-stream;1",
                                 "nsIStringInputStream");
var gConverterToPostList = null; // the singleton for the following XPCOM
                                 // service

function PostListConverter() {
  this.wrappedJSObject = this;
}

PostListConverter.prototype = {
  _listener: null, // this accepts the listener for displaying

  // nsIStreamConverter
  asyncConvertData: function asyncConvertData(aFromType, aToType, 
                                              aListener, aContext){
    this._listener = aListener;
    return;
  },
  convert: function convert(aFromStream, aFromType, aToType, aContext){
    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
  },
  
  // nsIStreamListener
  onDataAvailable: function onDataAvailable(aRequest, aContext, 
                                            aInputStream, aOffset, aCount){
    return; //nothing to do here because this converter needs no time to
            //the converting. The converter's job is done when 
            //onStartRequest(below) is finished
  },

  // nsIRequestObserver
  onStartRequest: function onStartRequest(aRequest, aContext) {
    if (!(aRequest instanceof Ci.nsIChannel))
      throw Cr.NS_ERROR_FAILURE;
    aRequest.contentType = "application/xhtml+xml";
    this._listener.onStartRequest(aRequest, aContext);
    if (this._usePost === null)
      dump("Error: The presentation choice is not set yet\n");
    if (!this._usePost)
      var channel = gIOService.newChannel(POSTLIST_URI, null, null);
    else
      var channel = gIOService.newChannel(POST_URI, null, null);
    this._usePost = null;
    var input = channel.open();
    var count = channel.contentLength;
    var stream = new Stream();
    stream.init(input);
    var templateData = stream.read(count);
    if (templateData.length !== count)
      throw "onStartRequest: content lengths don't match";
    
    var sis = new SIS();
    sis.setData(templateData, count);
    //@ move the following to onDataAvailable to make it normal?
    this._listener.onDataAvailable(aRequest, aContext, sis, 0, count);     
  },
  onStopRequest: function onStopRequest(aRequest, aContext, aNumber){
    this._listener.onStopRequest(aRequest, aContext, aNumber);  
  },

  // The following does the content type tweak 
  // text/html -> application/onthewave.postlist 
  _uriToConvert: "",
  _usePost: null,
  convertResource: function (aURIString, aBool){
    this._uriToConvert = aURIString;
    this._usePost = (aBool) ? true : false;
  },
  switchPresentation: function switchPresentation(aIsPost){
    this._usePost = aIsPost;
  },
   
  // The rest is for setting up the component
  classDescription: CLASS_NAME,
  classID: CLASS_ID,
  contractID: CONTRACT_ID,
  _xpcom_factory: {
    createInstance: function(aOuter, aIID) {
      if (aOuter != null)
        throw Components.results.NS_ERROR_NO_AGGREGATION;
      
      if (!gConverterToPostList)
        gConverterToPostList = new PostListConverter();
      
      return gConverterToPostList.QueryInterface(aIID);
    }
  },
  QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamConverter,
                                         Ci.nsIStreamListener,
                                         Ci.nsIRequestOvserver])  
};
 
function NSGetModule(compMgr, fileSpec) 
  XPCOMUtils.generateModule([PostListConverter])

